home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / programr / vbasic / bv0442.exe / HUGEARR.C < prev    next >
C/C++ Source or Header  |  1991-06-27  |  16KB  |  375 lines

  1. /************************************************************************
  2. *                                                                       *
  3. *                               HUGEARR.DLL                             *
  4. *                                                                       *
  5. *               Huge array support for Microsoft Visual Basic           *
  6. *                                                                       *
  7. *                             By Mike Warning                           *
  8. *                                                                       *
  9. ************************************************************************/
  10.  
  11. #include <memory.h>
  12. #include <windows.h>
  13. #include "hugearr.h"
  14.  
  15. HANDLE                  hLocalMem;              // handle to local memory
  16. int                     NumArrays;              // total number of arrays
  17.  
  18. /************************************************************************
  19. * LibMain -                                                             *
  20. *   Standard DLL constructor.  Allocates all of local heap to store     *
  21. * array descriptors and then set the total number of arrays possible.   *
  22. ************************************************************************/
  23. int FAR pascal
  24.      LibMain(HANDLE hModule, WORD wDataSeg, WORD cbHeapSize, LPSTR lpszCmdLine)
  25. {
  26.     if (cbHeapSize > 0)
  27.     UnlockData(0);
  28.                     // Allocate memory for array descrips.
  29.     hLocalMem = LocalAlloc(LMEM_MOVEABLE | LMEM_ZEROINIT,
  30.                          LocalCompact((WORD) 65500));
  31.     if (hLocalMem == NULL)
  32.     return 0;                       // Something happened, bomb out
  33.                     // calc total number of arrays
  34.     NumArrays = (int) (LocalSize(hLocalMem) / sizeof(struct ArrayDesc));
  35.     return (1);
  36. }
  37.  
  38. /************************************************************************
  39. * WEP -                                                                 *
  40. *   Standard DLL destructor.  Free up local memory and quit.            *
  41. ************************************************************************/
  42. int FAR pascal WEP(int bSystemExit)
  43. {
  44.     LocalFree(hLocalMem);
  45.     return (1);
  46. }
  47.  
  48. /************************************************************************
  49. * HugeDim -                                                             *
  50. *   Dimensions a new array.  The size of the array is                   *
  51. * (recsize * ubound+1). Recsize is the size in bytes of each element in *
  52. * the array and ubound is the upper bound of the array. All arrays have *
  53. * a lower bound of 0.                                                   *
  54. *                                                                       *
  55. * Note: If total size of the array is greater than 64k, recsize should  *
  56. *       be an integer power of two (1,2,4,8,16,etc.)  Otherwise, the    *
  57. *       huge pointers will not be added correctly.                      *
  58. ************************************************************************/
  59. int FAR pascal HugeDim(int recsize, long ubound)
  60. {
  61.     int         hArray;                 // handle to array to dimension
  62.     pDescrip    pArray;                 // pointer to array descriptor
  63.     int         ret;                    // return value from HugeAlloc
  64.  
  65.     pArray = (pDescrip) LocalLock(hLocalMem);   // find a free array
  66.     if ((hArray = GetFreeArray(pArray)) == HA_TOMANYARRAYS)  {
  67.     LocalUnlock(hLocalMem);                 // couldn't find one,
  68.     return (HA_TOMANYARRAYS);               // return error.
  69.     }
  70.                     // allocate new array
  71.     ret = HugeAlloc(pArray + hArray, recsize, ubound, FALSE);
  72.     LocalUnlock(hLocalMem);
  73.  
  74.     if (ret < 0)                        // if an error occured during alloc
  75.     return (ret);                   // return the error, else
  76.     else
  77.     return (hArray);                // return the handle to the array
  78. }
  79.  
  80. /************************************************************************
  81. * HugeRedim -                                                           *
  82. *   Redimenions the given array to have the new 'ubound'.  The old      *
  83. * recsize is kept.  All data in the array is preserved and any new data *
  84. * (created by expanding the array) is initialized to 0.                 *
  85. *                                                                       *
  86. * Note: The recsize must be an integer power of two if the total array  *
  87. *       size is greater than 64k.                                       *
  88. ************************************************************************/
  89. int FAR pascal HugeRedim(int hArray, long ubound)
  90. {
  91.     pDescrip    pArray;                 // pointer to array desciptor
  92.     register    ret;                    // return code of HugeAlloc
  93.  
  94.     if (hArray < 0 | hArray >= NumArrays)
  95.     return (HA_BADARRAY);           // illegal array handle
  96.  
  97.     pArray = (pDescrip) LocalLock(hLocalMem) + hArray;
  98.  
  99.     if (pArray -> handle != NULL)       // reallocate array
  100.     ret = HugeAlloc(pArray, pArray -> recsize, ubound, TRUE);
  101.     else
  102.     ret = HA_BADARRAY;              // array has never been allocated
  103.  
  104.     LocalUnlock(hLocalMem);
  105.     return (ret);
  106. }
  107.  
  108.  
  109. /********************************************************************
  110. * GetFreeArray -                                                    *
  111. *   Searches the array descriptor table looking for a free entry.   *
  112. * It returns the index into the table if an entry is free or        *
  113. * HA_TOMANYARRAYS otherwise.  pArray is the pointer to the start of *
  114. * the table.                                                        *
  115. ********************************************************************/
  116. int GetFreeArray(pDescrip pArray)
  117. {
  118.     int i = 0;
  119.                     // loop until found or out of entries
  120.     while ((i < NumArrays) && (pArray -> handle != NULL))  {
  121.     ++pArray;
  122.     ++i;
  123.     }
  124.  
  125.     if (i == NumArrays)                 // didn't find a spot
  126.     return (HA_TOMANYARRAYS);
  127.  
  128.     return (i);                         // found one, return index to it
  129. }
  130.  
  131. /********************************************************************
  132. * GetHugeEl -                                                       *
  133. *   Retrieves an element of the array storing it into the buffer    *
  134. * pointed to by 'buffer'.  hArray is the index into the descriptor  *
  135. * table of the array, element is the element to get.                *
  136. *                                                                   *
  137. * NOTE: there is absolutely no type checking done on the buffer.    *
  138. *       It is up to the programmer to make sure it points to the    *
  139. *       correct data type.                                          *
  140. ********************************************************************/
  141. int FAR pascal GetHugeEl(int hArray, long element, BYTE FAR *buffer)
  142. {
  143.     BYTE _huge          *ptr;               // pointer to array element
  144.     pDescrip            pArray;             // pointer to array descriptor
  145.  
  146.     if (hArray < 0 || hArray >= NumArrays)
  147.     return (HA_BADARRAY);               // illegal array handle
  148.  
  149.                         // point to proper descriptor
  150.     pArray = (pDescrip) LocalLock(hLocalMem) + hArray;
  151.  
  152.     if (pArray -> handle == NULL)  {
  153.     LocalUnlock(hLocalMem);
  154.     return (HA_BADARRAY);               // array hasn't been allocated
  155.     }
  156.     if ((pArray -> ubound < element) || (element < 0))  {
  157.     LocalUnlock(hLocalMem);
  158.     return (HA_SUBSCRIPT);              // subscript out of range
  159.     }
  160.                         // calculate pointer to element
  161.     ptr = (BYTE _huge *) GlobalLock(pArray -> handle);
  162.     ptr = ptr + element * pArray->recsize;
  163.     _fmemcpy(buffer, ptr, pArray -> recsize);   // copy data
  164.  
  165.     GlobalUnlock(pArray -> handle);
  166.     LocalUnlock(hLocalMem);
  167.     return (HA_OK);
  168. }
  169.  
  170. /********************************************************************
  171. * SetHugeEl -                                                       *
  172. *   Sets the value of an array element.  This routine is exactly    *
  173. * the same as 'GetHugeEl' except that the memory copy is resversed. *
  174. ********************************************************************/
  175. int FAR pascal SetHugeEl(int hArray, long element, BYTE FAR *buffer)
  176. {
  177.     BYTE _huge          *ptr;               // pointer to array element
  178.     pDescrip            pArray;             // pointer to array descriptor
  179.  
  180.     if (hArray < 0 || hArray >= NumArrays)
  181.     return (HA_BADARRAY);               // illegal array handle
  182.  
  183.                         // point to proper descriptor
  184.     pArray = (pDescrip) LocalLock(hLocalMem) + hArray;
  185.  
  186.     if (pArray -> handle == NULL)  {
  187.     LocalUnlock(hLocalMem);
  188.     return (HA_BADARRAY);               // array hasn't been allocated
  189.     }
  190.     if ((pArray -> ubound < element) || (element < 0))  {
  191.     LocalUnlock(hLocalMem);
  192.     return (HA_SUBSCRIPT);              // subscript out of range
  193.     }
  194.                         // calculate pointer to element
  195.     ptr = (BYTE _huge *) GlobalLock(pArray -> handle);
  196.     ptr = ptr + element * pArray->recsize;
  197.     _fmemcpy(ptr, buffer, pArray -> recsize);   // copy data
  198.  
  199.     GlobalUnlock(pArray -> handle);
  200.     LocalUnlock(hLocalMem);
  201.     return (HA_OK);
  202. }
  203.  
  204. /********************************************************************
  205. * HugeErase -                                                       *
  206. *   Deletes an array and marks it as free in the descriptor table.  *
  207. * 'hArray' is the array to erase.                                   *
  208. ********************************************************************/
  209. int FAR pascal HugeErase(int hArray)
  210. {
  211.     pDescrip    pArray;                     // pointer to array descriptor
  212.  
  213.     if (hArray < 0 || hArray >= NumArrays)
  214.     return (HA_BADARRAY);               // illegal array handle
  215.  
  216.     pArray = (pDescrip) LocalLock(hLocalMem) + hArray;
  217.     if (pArray -> handle == NULL)  {
  218.     LocalUnlock(hLocalMem);
  219.     return (HA_BADARRAY);               // array hasn't been allocated yet
  220.     }
  221.  
  222.     GlobalFree(pArray -> handle);           // free the memory
  223.     pArray -> handle = NULL;
  224.  
  225.     LocalUnlock(hLocalMem);
  226.     return (HA_OK);
  227. }
  228.  
  229. /********************************************************************
  230. * NumHugeArrays -                                                   *
  231. *   Returns the number of free entries in the array descriptor table*
  232. ********************************************************************/
  233. int FAR pascal NumHugeArrays(void)
  234. {
  235.     pDescrip            pArray;             // pointer to current descriptor
  236.     int                 num, i;             // number free so far
  237.  
  238.     pArray = (pDescrip) LocalLock(hLocalMem);
  239.     for (i = 0, num = 0; i < NumArrays; i++, pArray++)
  240.     if (pArray -> handle == NULL)
  241.         ++num;
  242.  
  243.     LocalUnlock(hLocalMem);
  244.     return (num);
  245. }
  246.  
  247.  
  248. /********************************************************************
  249. * HugeUbound -                                                      *
  250. *   Returns the upper bound of a given array                        *
  251. ********************************************************************/
  252. long FAR pascal HugeUbound(int hArray)
  253. {
  254.     pDescrip    pArray;                     // pointer to array descriptor
  255.     long    ubound;                     // upper bound of array
  256.  
  257.     if (hArray < 0 || hArray >= NumArrays)
  258.     return (HA_BADARRAY);               // illegal array handle
  259.  
  260.     pArray = (pDescrip) LocalLock(hLocalMem) + hArray;
  261.     if (pArray -> handle == NULL)  {
  262.     LocalUnlock(hLocalMem);
  263.     return (HA_BADARRAY);               // array hasn't been allocated yet
  264.     }
  265.  
  266.     ubound = pArray -> ubound;
  267.     LocalUnlock(hLocalMem);
  268.  
  269.     return (ubound);
  270. }
  271.  
  272.  
  273. /********************************************************************
  274. * HugeInt -                                                         *
  275. *   Same as GetHugeEl except that it explicitly returns an integer. *
  276. * Use this function when you are in an expression such as:          *
  277. *           i% = 5 * HugeInt(4, 5)                                  *
  278. *                                                                   *
  279. * NOTE: Because the user could store anything in the array element, *
  280. *       they will not know if the value returned is a real value or *
  281. *       if an error occured.  Use GetHugeEl if the error code must  *
  282. *       be checked.                                                 *
  283. ********************************************************************/
  284. int FAR pascal HugeInt(int hArray, long element)
  285. {
  286.     int     retval;
  287.  
  288.     GetHugeEl(hArray, element, (BYTE FAR *) &retval);
  289.     return (retval);
  290. }
  291.  
  292.  
  293. /********************************************************************
  294. * HugeLong -                                                        *
  295. *   Returns an element of a long integer array.  (re. HugeInt)      *
  296. ********************************************************************/
  297. long FAR pascal HugeLong(int hArray, long element)
  298. {
  299.     long    retval;
  300.  
  301.     GetHugeEl(hArray, element, (BYTE FAR *) &retval);
  302.     return (retval);
  303. }
  304.  
  305.  
  306.  
  307. /********************************************************************
  308. * HugeSingle -                                                      *
  309. *   Returns an element of a single precesion array.  (re. HugeInt)  *
  310. ********************************************************************/
  311. float FAR pascal HugeSingle(int hArray, long element)
  312. {
  313.     float  retval;
  314.  
  315.     GetHugeEl(hArray, element, (BYTE FAR *) &retval);
  316.     return (retval);
  317. }
  318.  
  319.  
  320. /********************************************************************
  321. * HugeDouble -                                                      *
  322. *   Returns an element of a double precesion array.  (re. HugeInt)  *
  323. ********************************************************************/
  324. double FAR pascal HugeDouble(int hArray, long element)
  325. {
  326.     double  retval;
  327.  
  328.     GetHugeEl(hArray, element, (BYTE FAR *) &retval);
  329.     return (retval);
  330. }
  331.  
  332.  
  333. /********************************************************************
  334. * HugeCurrency -                                                    *
  335. *   Returns an element of a currency array.  (re. HugeInt)          *
  336. ********************************************************************/
  337. currency FAR pascal HugeCurrency(int hArray, long element)
  338. {
  339.     return((currency) HugeDouble(hArray, element));
  340. }
  341.  
  342. /********************************************************************
  343. *   HugeAlloc -                                                     *
  344. * Allocates (or reallocates) global memory for an array.  The size  *
  345. * of the array is recsize * (ubound + 1) bytes.  The information    *
  346. * for the array is stored in the array descriptor pointed to by     *
  347. * 'pArray'.                                                         *
  348. *                                                                   *
  349. * Note:  See HugeDim for a discussion on array size limitations.    *
  350. ********************************************************************/
  351. int HugeAlloc(pDescrip pArray,int recsize,long ubound, BOOL realloc)
  352. {
  353.     HANDLE              handle;             // temp handle for alloc
  354.  
  355.     ++ubound;                               // ubound = #elements - 1
  356.     if (recsize * ubound > 0xffff)          // is size integer power two?
  357.     if ((recsize <= 0) || (((recsize - 1) & recsize) != 0))
  358.         return (HA_BADELEMENTSIZE);
  359.  
  360.     if (realloc)                            // allocate array
  361.     handle = GlobalReAlloc(pArray -> handle, recsize * ubound,
  362.                            GMEM_MOVEABLE || GMEM_ZEROINIT);
  363.     else
  364.     handle = GlobalAlloc(GMEM_MOVEABLE || GMEM_ZEROINIT, recsize * ubound);
  365.  
  366.     if (handle == NULL)
  367.     return (HA_OUTOFMEMORY);            // out of memory
  368.  
  369.     pArray -> handle = handle;              // save new handle
  370.     pArray -> recsize = recsize;            // record element size
  371.     pArray -> ubound = ubound - 1;
  372.  
  373.     return (HA_OK);
  374. }
  375.